//
// Created by mi on 2024/4/30.
//

//https://blog.csdn.net/zwvista/article/details/81193433
#include <variant>
#include <string>
#include <iostream>

using namespace std;

//仿函数多种
class MyVisitor
{
public:
    void operator()(int i) { cout << "int " << i << endl; }
    void operator()(const string& s) { cout << "string " << s << endl; }
    void operator()(float f) { cout << "float " << f << endl; }
};
//variant 是 C++17 所提供的变体类型。variant<X, Y, Z> 是可存放 X, Y, Z 这三种类型数据的变体类型。
//
//与C语言中传统的 union 类型相同的是，variant 也是联合(union)类型。即 variant 可以存放多种类型的数据，但任何时刻最多只能存放其中一种类型的数据。
//与C语言中传统的 union 类型所不同的是，variant 是可辨识的类型安全的联合(union)类型。即 variant 无须借助外力只需要通过查询自身就可辨别实际所存放数据的类型。
int main()
{
    variant<int, float,string> v;
    v = 12;

    v = 12.5f;
    v = "An std::string";

    cout << "Type index: " << v.index() << endl;
    cout << "Contains an int: " << holds_alternative<int>(v) << endl;

    cout << std::get<string>(v) << endl;
    try {
        cout << std::get<0>(v) << endl;
    } catch (const bad_variant_access& ex) {
        cout << "Exception: " << ex.what() << endl;
    }

    string* theString = std::get_if<string>(&v);
    int* theInt = std::get_if<int>(&v);
    cout << "retrieved string: " << (theString ? *theString : "null") << endl;
    cout << "retrieved int: " << (theInt ? *theInt : 0) << endl;

    std::visit(MyVisitor(), v);

    return 0;
}
